package achi.community.irla.database;

//import achi.community.irla.entities.Friends;
import achi.community.irla.entities.Achievements;
import achi.community.irla.entities.Achievements_comments;
import achi.community.irla.entities.Achievements_completed;
import achi.community.irla.entities.Achievements_suggested;
import achi.community.irla.entities.Achievements_target;
import achi.community.irla.entities.Friends;
import achi.community.irla.entities.Messages;
//import achi.community.irla.entities.Messages_users;
import achi.community.irla.entities.Users;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;

@Stateless
public class DatabaseImpl {

    private final static String TestPUName = "irla_pu";
    private final static String PUName = "jpa_pu";
    @PersistenceContext(unitName = "jpa_pu")
    private EntityManager em;
    // @PersistenceContext(unitName = PUName)
    // private EntityManager em;

    public void addUser(Users user) {

        em.persist(user);

        // Update that the user exist in case the User is removed in example. Friend table
        em.flush();
        em.clear();
    }

    public void updateUser(Users user) {
        em.merge(user);
    }

    public void addAchievement(Achievements a) {
        em.persist(a);

        // Update that the user exist in case the User is removed in example. Friend table
        em.flush();
        em.clear();
    }

    public void addAchievement_comment(Achievements_comments a, Long userId, Long achiID) {
        Users u = getUser(userId);
        Achievements achi = getAchievement(achiID);
        a.setUser(u);
        a.setAchievement(achi);
        em.persist(a);
    }

    public void addAchievement_completed(Achievements_completed a, Long userId, Long achiID) {
        Users u = getUser(userId);
        Achievements achi = getAchievement(achiID);
        a.setUser(u);
        a.setAchievement(achi);
        em.persist(a);
    }

    public void addAchievement_suggested(Achievements_suggested a, Long userId, Long achiID) {
        Users u = getUser(userId);
        Achievements achi = getAchievement(achiID);
        a.setUser(u);
        a.setAchievement(achi);
        em.persist(a);
    }

    public void initAchievement_target(Long userId, String pos) {
        Achievements_target a = new Achievements_target();
        Achievements achi = getAchievement(new Long(0));
        Users u = getUser(userId);
        a.setAchievement(achi);
        a.setUser(u);

        //a.setTa(achi);
        //a.setTb(achi);
        //a.setTc(achi);
        //a.setTd(achi);
        //a.setTe(achi);

        a.setPos(pos);
        em.persist(a);
    }

    public void initAchievement_completed(Long userId, String pos) {
        Achievements_completed a = new Achievements_completed();
        Achievements achi = getAchievement(new Long(0));
        Users u = getUser(userId);
        a.setAchievement(achi);
        a.setUser(u);

        a.setPos(pos);
        em.persist(a);
    }

    public void addMessage(Messages msg, Long UserId) {
        String query = "SELECT u FROM Users u WHERE u.id = " + UserId;
        TypedQuery<Users> tq = em.createQuery(query, Users.class);
        Users usr = tq.getSingleResult();
        List<Messages> msgs = usr.getMessages();
        msgs.add(msg);
        usr.setMessages(msgs);
        em.persist(usr);

        msg.setUser(usr);
        em.persist(msg);
    }

    public void addFriend(Long userID, Long friendID) {
        Users u = getUser(userID);
        Users f = getUser(friendID);
        Friends friends = new Friends(u, f);

        em.persist(friends);
    }

    public Users getUser(Long id) {
        String query = "SELECT u FROM Users u WHERE u.id = '" + id + "'";
        TypedQuery<Users> tq = em.createQuery(query, Users.class);
        Users user = tq.getSingleResult();
        return user;
    }

    public Users getUser2(String mail) {
        String query = "SELECT u FROM Users u WHERE u.email = '" + mail + "'";
        TypedQuery<Users> tq = em.createQuery(query, Users.class);
        Users user = tq.getSingleResult();
        return user;
    }

    public boolean userExists(String mail) {
        String query = "SELECT u FROM Users u WHERE u.email = '" + mail + "'";
        TypedQuery<Users> tq = em.createQuery(query, Users.class);
        List<Users> ulist = tq.getResultList();
        int resSize = ulist.size();
        System.out.println("size:" + resSize);

        if (resSize == 1) {
            return true;
        } else {
            return false;
        }
    }

    public Achievements getAchievement(Long id) {
        String query = "SELECT a FROM Achievements a WHERE a.id = '" + id + "'";
        TypedQuery<Achievements> tq = em.createQuery(query, Achievements.class);
        Achievements achi = tq.getSingleResult();
        return achi;
    }

    public List<Users> getAllUsers() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Users.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Messages> getAllMessages() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Messages.class));
        return em.createQuery(cq).getResultList();
    }

    /**
     * public List<Messages_users> getAllUMessages() { CriteriaQuery cq =
     * em.getCriteriaBuilder().createQuery();
     * cq.select(cq.from(Messages_users.class)); return
     * em.createQuery(cq).getResultList(); }
     */
    public List<Friends> getAllFriends() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Friends.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Friends> getAllAchievements() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Achievements.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Friends> getAllAchievements_comments() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Achievements_comments.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Friends> getAllAchievements_completed() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Achievements_completed.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Friends> getAllAchievements_suggested() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Achievements_suggested.class));
        return em.createQuery(cq).getResultList();
    }

    public List<Friends> getAllAchievements_target() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(Achievements_target.class));
        return em.createQuery(cq).getResultList();
    }

    public void removeUser(Long id) {
        String query = "SELECT u FROM Users u WHERE u.id = " + id;
        TypedQuery<Users> tq = em.createQuery(query, Users.class);
        Users user = tq.getSingleResult();

        em.remove(em.merge(user));
    }

    public void removeMessage(Long id) {
        String query = "SELECT m FROM Messages m WHERE m.id = " + id;
        TypedQuery<Messages> tq = em.createQuery(query, Messages.class);
        Messages msg = tq.getSingleResult();
        em.remove(em.merge(msg));
    }

    public void removeFriend(Long id) {
        String query = "SELECT f FROM Friends f WHERE f.id = " + id;
        TypedQuery<Friends> tq = em.createQuery(query, Friends.class);
        Friends f = tq.getSingleResult();
        em.remove(em.merge(f));
    }

    public void removeAchievement(Long id) {
        String query = "SELECT a FROM Achievements a WHERE a.id = " + id;
        TypedQuery<Achievements> tq = em.createQuery(query, Achievements.class);
        Achievements achi = tq.getSingleResult();
        em.remove(em.merge(achi));
    }

    public void removeAchievement_comment(Long id) {
        String query = "SELECT a FROM Achievements_comments a WHERE a.id = " + id;
        TypedQuery<Achievements_comments> tq = em.createQuery(query, Achievements_comments.class);
        Achievements_comments achi = tq.getSingleResult();
        em.remove(em.merge(achi));
    }

    public void removeAchievement_completed(Long id) {
        String query = "SELECT a FROM Achievements_completed a WHERE a.id = " + id;
        TypedQuery<Achievements_completed> tq = em.createQuery(query, Achievements_completed.class);
        Achievements_completed achi = tq.getSingleResult();
        em.remove(em.merge(achi));
    }

    public void removeAchievement_suggested(Long id) {
        String query = "SELECT a FROM Achievements_suggested a WHERE a.id = " + id;
        TypedQuery<Achievements_suggested> tq = em.createQuery(query, Achievements_suggested.class);
        Achievements_suggested achi = tq.getSingleResult();
        em.remove(em.merge(achi));
    }

    public void removeAchievement_target(Long id) {
        String query = "SELECT a FROM Achievements_target a WHERE a.id = " + id;
        TypedQuery<Achievements_target> tq = em.createQuery(query, Achievements_target.class);
        Achievements_target achi = tq.getSingleResult();
        em.remove(em.merge(achi));
    }

    /**
     * Customer customer = customerTQ.getSingleResult();
     *
     * String query = "select p from PurchaseOrder p where p.customer =
     * :customer"; TypedQuery<PurchaseOrder> tq = em.createQuery(query,
     * PurchaseOrder.class); tq.setParameter("customer", customer);
     * List<PurchaseOrder> orders = tq.getResultList();
     */
    public List<Achievements_target> getAchiTargets(Long userId) {
        String query = "SELECT a FROM Achievements_target a WHERE a.user = :user";
        //System.out.println("getUT query:" + query);
        TypedQuery<Achievements_target> tq = em.createQuery(query, Achievements_target.class);
        //System.out.println("tq done");
        Users user = getUser(userId);
        tq.setParameter("user", user);
        return tq.getResultList();
    }

    public Achievements_target getAchiTarget(Long userId, String pos) {
        String query = "SELECT a FROM Achievements_target a WHERE a.user = :user AND a.pos = :pos";
        TypedQuery<Achievements_target> tq = em.createQuery(query, Achievements_target.class);
        Users user = getUser(userId);
        tq.setParameter("user", user);
        tq.setParameter("pos", pos);
        return tq.getSingleResult();
    }
  /**  
    public Achievements_completed getAchiCompleted(Long userId, String pos) {
        String query = "SELECT a FROM Achievements_completed a WHERE a.user = :user AND a.pos = :pos";
        TypedQuery<Achievements_completed> tq = em.createQuery(query, Achievements_completed.class);
        Users user = getUser(userId);
        tq.setParameter("user", user);
        tq.setParameter("pos", pos);
        return tq.getSingleResult();
    }
*/
    public HashMap<String, Achievements> getUserTargets(Long id) {
        List<Achievements_target> res = getAchiTargets(id);

        HashMap map = new HashMap();
        for (int i = 0; i < res.size(); i++) {
            Achievements_target achi = res.get(i);
            map.put(achi.getPos(), achi.getAchievement());
        }
        /**
         * map.put("ta", res.getTa()); map.put("tb", res.getTb()); map.put("tc",
         * res.getTc()); map.put("td", res.getTd()); map.put("te", res.getTe());
         */
        //List<Achievements_target> achi = tq.getResultList();
        //System.out.println("getUT reslist1t:"+test.getId());
        //List<Achievements> res = new LinkedList();
        //for(Achievements_target a:achi){
        //  Achievements ta = a.getAchievement();
        //  res.add(ta);
        // }
        //System.out.println("getUT reslist2:"+res.size());
        return map;
    }

    public List<Achievements_completed> getAchiCompleted(Long userId) {
        String query = "SELECT a FROM Achievements_completed a WHERE a.user = :user";
        TypedQuery<Achievements_completed> tq = em.createQuery(query, Achievements_completed.class);
        Users user = getUser(userId);
        tq.setParameter("user", user);
        return tq.getResultList();
    }

    public Achievements_completed getAchiCompleted(String cId) {
        String query = "SELECT a FROM Achievements_completed a WHERE a.id = "+cId;
        TypedQuery<Achievements_completed> tq = em.createQuery(query, Achievements_completed.class);
        //Users user = getUser(userId);
        //tq.setParameter("user", user);
        return tq.getSingleResult();
    }

    public HashMap<String, Achievements_completed> getUserCompleted(Long id) {
        List<Achievements_completed> res = getAchiCompleted(id);
        HashMap map = new HashMap();
        for (int i = 0; i < res.size(); i++) {
            Achievements_completed achi = res.get(i);
            map.put(achi.getPos(), achi);
        }
        return map;
    }

    public void updateTarget(Long userId, String pos, Achievements achi) {
        Achievements_target target = getAchiTarget(userId, pos);
        target.setAchievement(achi);
        /**
         * if(col.equals("ta")) target.setTa(achi); else if(col.equals("tb"))
         * target.setTb(achi); else if(col.equals("tc")) target.setTc(achi);
         * else if(col.equals("td")) target.setTd(achi); else
         * if(col.equals("te")) target.setTe(achi);
         *
         */
        em.merge(target);
    }

    /**
    public void updateCompleted(Long userId, String pos, Achievements_completed achi) {
        Achievements_completed completed = getAchiCompleted(userId, pos);
        
        completed.setAchievement(achi);
        em.merge(completed);
    }
    */
    public void updateCompleted(Achievements_completed achi) {
        em.merge(achi);
    }
    /**
     * public void removeUMessage(int id) { String query = "SELECT m FROM
     * Messages_users m WHERE m.id = " + id; TypedQuery<Messages_users> tq =
     * em.createQuery(query, Messages_users.class); Messages_users msgu =
     * tq.getSingleResult(); em.remove(em.merge(msgu)); }
     *
     */
    // public void addUser(User user) {
    //       em.persist(user);
    //  }
    /**
     * public void setEM() { //totally breaking design pattern here
     * EntityManagerFactory emf =
     * Persistence.createEntityManagerFactory(TestPUName); this.em =
     * emf.createEntityManager(); }
     *
     * public boolean customerExists(String mail) { String query = "select p
     * from Customer p where p.email = '" + mail + "'"; TypedQuery<Customer> tq
     * = em.createQuery(query, Customer.class); List<Customer> clist =
     * tq.getResultList(); int resSize = clist.size();
     *
     * if (resSize == 1) { return true; } else { return false; } }
     *
     * public Customer getCustomer(String mail) { String query = "select p from
     * Customer p where p.email = '" + mail + "'"; TypedQuery<Customer> tq =
     * em.createQuery(query, Customer.class); Customer cust =
     * tq.getSingleResult();
     *
     * return cust; }
     *
     * public List<Animal> getAnimals() { CriteriaQuery cq =
     * em.getCriteriaBuilder().createQuery(); cq.select(cq.from(Animal.class));
     * return em.createQuery(cq).getResultList(); }
     *
     * public void addAnimal(Animal animal) { em.persist(animal); }
     *
     * public void addPurchaseOrder(PurchaseOrder order) { em.persist(order); }
     *
     * public void addOrderItem(OrderItem item) { em.persist(item); }
     *
     * public void removeAnimal(int id) { String query = "select p from Animal p
     * where p.id = " + id; TypedQuery<Animal> tq = em.createQuery(query,
     * Animal.class); Animal product = tq.getSingleResult();
     * em.remove(em.merge(product)); }
     *
     * public void updateAnimal(Animal product) { em.merge(product); }
     *
     * public Animal getAnimal(int id) { String query = "select p from Animal p
     * where p.id = " + id; TypedQuery<Animal> tq = em.createQuery(query,
     * Animal.class); Animal animal = tq.getSingleResult(); return animal; }
     *
     * public List<PurchaseOrder> getOrders(int custID) { String customerQuery =
     * "select c from Customer c where c.id = " + custID + "" ;
     * TypedQuery<Customer> customerTQ = em.createQuery(customerQuery,
     * Customer.class); Customer customer = customerTQ.getSingleResult();
     *
     * String query = "select p from PurchaseOrder p where p.customer =
     * :customer"; TypedQuery<PurchaseOrder> tq = em.createQuery(query,
     * PurchaseOrder.class); tq.setParameter("customer", customer);
     * List<PurchaseOrder> orders = tq.getResultList();
     *
     * return orders; }
     */
}
